<template>
  <el-dialog :title="showTitle" :visible="showDialog" width="50%" @close="handelClose">
    <!-- 表单组件  el-form   label-width设置label的宽度   -->
    <el-form ref="deptForm" label-width="120px" :model="formData" :rules="rules">
      <el-form-item label="部门名称" prop="name">
        <el-input v-model="formData.name" style="width: 80%" placeholder="1-50个字符" />
      </el-form-item>
      <el-form-item label="部门编码" prop="code">
        <el-input v-model="formData.code" style="width: 80%" placeholder="1-50个字符" />
      </el-form-item>
      <el-form-item label="部门负责人" prop="manager">
        <el-select v-model="formData.manager" style="width: 80%" placeholder="请选择" @focus="getManger">
          <el-option v-for="item in managers" :key="item.id" :label="item.username" :value="item.username" />
        </el-select>
      </el-form-item>
      <el-form-item label="部门介绍" prop="introduce">
        <el-input v-model="formData.introduce" style="width: 80%" placeholder="1-300个字符" type="textarea" :rows="3" />
      </el-form-item>
    </el-form>
    <!-- 匿名插槽 -->
    <el-row slot="footer" type="flex" justify="center">
      <el-col :span="6">
        <el-button @click="$emit('update:showDialog', false)">取 消</el-button>
        <el-button type="primary" @click="sumbitBtn">确 定</el-button>
      </el-col>
    </el-row>
  </el-dialog>
</template>

<script>
import { getDepartments, addDepartments, editDepartments } from '@/api/departments'
import { getSimpleEmployes } from '@/api/employees'
export default {
  props: {
    // 对话框的显示状态
    showDialog: {
      type: Boolean,
      default: false
    },
    // 父节点
    pNode: {
      type: Object,
      default: () => ({})
    },
    // 当前要编辑的节点
    currentNode: {
      type: Object,
      default: () => ({})
    },
    // 要显示的对话框标题
    showTitle: {
      type: String,
      default: ''
    }
  },
  data() {
    // 部门名称的校验规则：
    // 添加时：同部门(同一个父级)下不能重名
    // 编辑时：同部门(同一个父级)下不能重名，排除掉自己(如不修改部门名称)
    const checkNameRepeat = async (rules, value, callback) => {
      // 先获取最新的所有部门数据：有可能你在操作的时候别人也在做添加操作
      const { depts } = await getDepartments()
      let isReat = false
      if (this.formData.id) {
        // 编辑
        // 先找子级，再找输入的部门名称和自己的名称有没有相同的,并且排除掉自己
        isReat = depts.filter(item => item.pid === this.pNode.id && item.id !== this.formData.id).some(item => item.name === value)
      } else {
        // 添加
        // 先找子级，再找输入的部门名称和自己的名称有没有相同的
        isReat = depts.filter(item => item.pid === this.pNode.id).some(item => item.name === value)
      }

      isReat ? callback(new Error('部门名称重复')) : callback()
    }
    // 部门编码的校验规则：
    // 添加时：所有部门中都不能重复
    // 修改时：所有部门中都不能重复，也要排除自己
    const checkCodeRepeat = async (rules, value, callback) => {
      // 先获取最新的所有部门数据：有可能你在操作的时候别人也在做添加操作
      const { depts } = await getDepartments()
      let isReat = false
      if (this.formData.id) {
        isReat = depts.some(item => item.code === value && item.id !== this.formData.id)
      } else {
        isReat = depts.some(item => item.code === value)
      }
      isReat ? callback(new Error('部门编码重复')) : callback()
    }
    return {
      formData: {
        name: '', // 部门名称
        code: '', // 部门编码
        manager: '', // 部门管理者
        introduce: '' // 部门介绍
      },
      rules: {
        name: [
          { required: true, message: '部门名称不能为空', trigger: 'blur' },
          // 定义自定义校验规则验证部门名称
          { validator: checkNameRepeat, trigger: 'blur' }
        ],
        code: [
          { required: true, message: '部门编码不能为空', trigger: 'blur' },
          { validator: checkCodeRepeat, trigger: 'blur' }
        ],
        manager: [{ required: true, message: '部门负责人不能为空', trigger: 'blur' }],
        introduce: [
          { required: true, message: '部门介绍不能为空', trigger: 'blur' },
          { min: 1, max: 300, trigger: 'blur', message: '部门介绍要求1-300个字符' }
        ]
      },
      // 所有的管理员数据
      managers: []
    }
  },
  watch: {
    // 侦听修改操作
    '$props.currentNode': {
      handler(newValue) {
        // 修改时给表单赋值
        // 这种赋值形成浅拷贝，两个对象是同一个对象，相当于地址的赋值
        // this.formData = newValue
        // 得使用这种方式，或者使用lodash里面的方法cloneDeep()
        Object.keys(newValue).forEach(key => {
          this.formData[key] = newValue[key]
        })
      },
      immediate: true,
      deep: true
    }
  },
  methods: {
    // 获取管理员
    async getManger() {
      this.managers = await getSimpleEmployes()
    },
    // 提交表单
    sumbitBtn() {
      // 校验
      this.$refs.deptForm.validate(async valid => {
        // 校验不通过
        if (!valid) return false
        try {
          // 判断是添加还是修改
          if (this.formData.id) {
            await editDepartments(this.formData)
            // 修改成功后
            // 3.重置表单选项
            // 提示信息
            this.$message.success('修改部门成功')
          } else {
            // 校验通过
            await addDepartments({ ...this.formData, pid: this.pNode.id })
            // 添加成功后
            // 提示信息
            this.$message.success('添加部门成功')
          }
          // 1.重新获取列表的最新数据
          this.$emit('addDepts')
          //  2.关闭对话框
          this.$emit('update:showDialog', false)
        } catch (err) {
          // 1.重新获取列表的最新数据
          this.$emit('addDepts')
          //  2.关闭对话框
          this.$emit('update:showDialog', false)
        }
      })
    },
    // 监听对话框关闭事件
    handelClose() {
      //  1.关闭对话框
      this.$emit('update:showDialog', false)
      // 2.重置表单
      this.$refs.deptForm.resetFields()
      // 3.将formData的数据置空
      Object.keys(this.formData).forEach(key => {
        this.formData[key] = ''
      })
      this.$emit('update:currentNode', {})
    }
  }
}
</script>

<style lang="scss" scoped></style>
